import {Vec3} from "../math";
import {IOriginVertexData} from "./originDtata";

const tmpv1 = new Vec3();
const tmpv2 = new Vec3();
const tmpv3 = new Vec3();

const v0 = new Vec3();
const v1 = new Vec3();
const v2 = new Vec3();

interface IV{
    [index:number]:number[]
}

interface IF{
    [index:number]:Vec3
}

/**
 *
 * @param  data:{
    positions: number[],
    normals: number[],
    texCoords: number[],
    indices: number[]
}
 */
export function computeNormals(data:IOriginVertexData) {

    let indices = data.indices;
    let positions = data.positions;
    data.normals.length = data.positions.length;

    let v01 = tmpv1;
    let v12 = tmpv2;
    let nor = tmpv3;

    // 先计算所有的面法线
    let faceLen = indices.length / 3;
    let f = {} as IF;
    let v = {} as IV;  // 顶点索引i属于 哪几个面
    for (let i = 0; i < faceLen; ++i) {
        let i0 = indices[3 * i];
        let i1 = indices[3 * i + 1];
        let i2 = indices[3 * i + 2];

        if (!v[i0]) {
            v[i0] = [];
        }
        v[i0].push(i);

        if (!v[i1]) {
            v[i1] = [];
        }
        v[i1].push(i);

        if (!v[i2]) {
            v[i2] = [];
        }
        v[i2].push(i);


        v0.set(positions[3 * i0], positions[3 * i0 + 1], positions[3 * i0 + 2]);
        v1.set(positions[3 * i1], positions[3 * i1 + 1], positions[3 * i1 + 2]);
        v2.set(positions[3 * i2], positions[3 * i2 + 1], positions[3 * i2 + 2]);

        Vec3.subtract(v01,v1,v0);
        Vec3.subtract(v12,v2,v1);
        Vec3.cross(nor,v01,v12);
        nor.normalize();
        f[i] = new Vec3(nor.x, nor.y, nor.z);
    }

    // 计算顶点的平均法线
    let posLen = positions.length / 3;
    let sum = tmpv1;
    for (let i = 0; i < posLen; ++i) {
        sum.set(0, 0, 0);
        v[i].forEach(faceIdx => {
            sum.add(f[faceIdx]);
        });
        sum.normalize();
        data.normals[3 * i] = sum.x;
        data.normals[3 * i + 1] = sum.y;
        data.normals[3 * i + 2] = sum.z;
    }
}

